package utils;

import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.util.List;

/**
 * @author: dm
 * @date: 2023/1/3 14:11
 * @description:
 */
public class ImageUtils {
    /**
     * 合成任意数量的图片
     * @param isHorizontal
     * @param imgs
     * @return
     * @throws IOException
     */
    public static BufferedImage mergeImage(boolean isHorizontal, List<BufferedImage> imgs) throws IOException {
        // 生成新图片
        BufferedImage DestImage = null;
        // 计算新图片的长和高
        int allw = 0, allh = 0, allwMax = 0, allhMax = 0;
        for (BufferedImage img : imgs) {
            allw += img.getWidth();
            allh += img.getHeight();
            if (img.getWidth() > allwMax) {
                allwMax = img.getWidth();
            }
            if (img.getHeight() > allhMax) {
                allhMax = img.getHeight();
            }
        }
        // 创建新图片
        if (isHorizontal) {
            DestImage = new BufferedImage(allw, allhMax, BufferedImage.TYPE_INT_RGB);
        } else {
            DestImage = new BufferedImage(allwMax, allh, BufferedImage.TYPE_INT_RGB);
        }

        // 合并所有子图片到新图片
        int wx = 0, wy = 0;
        for (BufferedImage img : imgs) {
            int w1 = img.getWidth();
            int h1 = img.getHeight();
            // 从图片中读取RGB
            int[] ImageArrayOne = new int[w1 * h1 + w1];
            ImageArrayOne = img.getRGB(0, 0, w1, h1, ImageArrayOne, 0, w1); // 逐行扫描图像中各个像素的RGB到数组中
            if (isHorizontal) { // 水平方向合并
                DestImage.setRGB(wx, 0, w1, h1, ImageArrayOne, 0, w1); // 设置上半部分或左半部分的RGB
            } else { // 垂直方向合并
                DestImage.setRGB(0, wy, w1, h1, ImageArrayOne, 0, w1); // 设置上半部分或左半部分的RGB
            }
            wx += w1;
            wy += h1;
        }
        return DestImage;
    }

    /**
     * 为图片添加字符串水印
     * @param image
     * @param color
     * @param font
     * @param watermarkContent
     * @return
     */
    public static BufferedImage addWatermark(BufferedImage image, Color color, Font font, String watermarkContent) {
        //获取原图片的宽高
        int height = image.getHeight();
        int width = image.getWidth();
        //加水印
        Graphics2D g = image.createGraphics();
        g.drawImage(image, 0, 0, width, height, null);
        g.setColor(color);
        g.setFont(font);

        //设置水印坐标
        int x = width - 2 * g.getFontMetrics(g.getFont()).charsWidth(watermarkContent.toCharArray(), 0, watermarkContent.length());
        int y = height - 2 * g.getFontMetrics(g.getFont()).charsWidth(watermarkContent.toCharArray(), 0, watermarkContent.length());
        g.drawString(watermarkContent, x, y);
        g.dispose();

        return image;
    }

    /**
     * 为图片添加图片水印
     * @param image
     * @param color
     * @param font
     * @param targetImage
     * @return
     */
    public static BufferedImage addWatermark(BufferedImage image, Color color, Font font, BufferedImage targetImage) {
        //获取原图片的宽高
        int height = image.getHeight();
        int width = image.getWidth();
        //加水印
        Graphics2D g = image.createGraphics();
        g.drawImage(image, 0, 0, width, height, null);
        g.setColor(color);
        g.setFont(font);

        //设置水印坐标
        int x = width - 2 * targetImage.getWidth();
        int y = height - 2 * targetImage.getHeight();
        g.drawImage(targetImage, x, y, targetImage.getWidth(), targetImage.getHeight(), null);
        g.dispose();

        return image;
    }

    /**
     * 缩小图片
     * @param image
     * @param a     缩小的倍数
     * @return
     */
    public static BufferedImage reduce(BufferedImage image, int a) {
        int width = image.getWidth();
        int height = image.getHeight();
        int[] data = new int[width * height];
        data = image.getRGB(0, 0, width, height, data, 0, width);
        int newWidth = width / a;
        int newHeight = height / a;

        int[] newData = new int[newWidth * newHeight];
        for (int y = 0; y < newHeight; y++) {
            for (int x = 0; x < newWidth; x++) {
                newData[x + y * newWidth] = data[a * x + a * y * width];
            }
        }
        BufferedImage bufferedImage = new BufferedImage(newWidth, newHeight, BufferedImage.TYPE_INT_RGB);
        bufferedImage.setRGB(0, 0, newWidth, newHeight, newData, 0, newWidth);
        return bufferedImage;
    }

    /**
     * 扩大图片
     * @param image
     * @param a
     */
    public static BufferedImage expand(BufferedImage image, int a) {
        int width = image.getWidth();
        int height = image.getHeight();
        int[] data = new int[width * height];
        data = image.getRGB(0, 0, width, height, data, 0, width);
        int newWidth = width * a;
        int newHeight = height * a;

        int[] newData = new int[newWidth * newHeight];
        for (int y = 0; y < height; y++) {
            for (int x = 0; x < width; x++) {
                newData[a * x + a * y * a * width] = data[x + y * width];
            }
        }
        for (int y = 0; y < newHeight; y++) {
            for (int x = 0; x < newWidth; x++) {
                if(y%2 == 1) {
                    newData[x + y * newWidth] = newData[x + (y - 1) * newWidth];
                }
                if(x%2 == 1) {
                    newData[x + y * newWidth] = newData[x - 1 + y * newWidth];
                }
            }

        }
        BufferedImage bufferedImage = new BufferedImage(newWidth, newHeight, BufferedImage.TYPE_INT_RGB);
        bufferedImage.setRGB(0, 0, newWidth, newHeight, newData, 0, newWidth);
        return bufferedImage;
    }
}
